#include "StdAfx.h"
#include "cSceneManager.h"
#define GETLINE(format, ...) fgets(line, 255, f);sscanf(line, format, __VA_ARGS__);printf("%s",line);
cSceneManager* cSceneManager::m_instance = NULL;
cSceneManager::cSceneManager(void)
{
	myShaders.Init("../Resources/Shaders/FrameShaderVS.vs","../Resources/Shaders/FrameShaderFS.fs");
	fbo.Init();
	model.Init("../Resources/Models/rectangle.nfg");

	m_Objects = NULL;
	m_numObject = 0;
	totalTime= 0.0f;
}

cSceneManager::~cSceneManager(void)
{
	if(m_Objects)
	{
		if(m_Objects->m_texture)
			delete[] m_Objects->m_texture;
		 m_Objects->m_texture = NULL;

		 if( m_Objects->m_texturesCube)
			delete[]  m_Objects->m_texturesCube;
		 m_Objects->m_texturesCube = NULL;

	//	delete &myShaders;
	//	&myShaders = NULL;



		delete[] m_Objects;
	}
	m_Objects = NULL;
}
cSceneManager * cSceneManager::GetInstance()
{
	if(m_instance == NULL)
	{
		m_instance = new cSceneManager();
	}
	return m_instance;
}
void cSceneManager::destroy()
{
	//~SceneManager();
	
	if(m_instance)
	{
		m_instance->myShaders.cleanUp();
		delete m_instance;
	}
	m_instance = NULL;

	//myShaders = NULL;

}
int cSceneManager::Init(const char *fileName)
{
	FILE *f;
	char line[256];
	int value;
	f = fopen(fileName,"rt");
	int id, modelID;
	if(f == NULL)
		return 0;
	GETLINE("#Objects: %d", &m_numObject);
	m_Objects = new cObject[m_numObject];
	for(int i = 0; i < m_numObject; ++i)
	{
		GETLINE("ID %d", &id);
		m_Objects[i].id = id;
		GETLINE("MODEL %d", &modelID);
		m_Objects[i].m_Model = cResourceManager::GetInstance()->GetModel(modelID);
		GETLINE("TEXTURES %d", &m_Objects[i].numOfTexture);
		(m_Objects[i].m_texture) = new cTexture*[ m_Objects[i].numOfTexture];


		for (int j = 0; j < m_Objects[i].numOfTexture; ++j)
		{
			GETLINE("TEXTURE %d",&value);
			m_Objects[i].m_texture[j]= (cResourceManager::GetInstance()->GetTexture(value));		
		}
		GETLINE("CUBETEXTURES %d", &m_Objects[i].numOfTextureCube);
		m_Objects[i].m_texturesCube = new cTexturesCube[ m_Objects[i].numOfTextureCube];
		for (int j = 0; j < m_Objects[i].numOfTextureCube; ++j)
		{
			GETLINE("CUBETEX %d",&value);
			m_Objects[i].m_texturesCube[j] = *(cResourceManager::GetInstance()->GetTextureCube(value));
		}
		GETLINE("SHADER %d",&value);
		m_Objects[i].m_Shader = cResourceManager::GetInstance()->GetShader(value);
		
		GETLINE("POSITION %f, %f, %f", &m_Objects[i].m_position.x, &m_Objects[i].m_position.y, &m_Objects[i].m_position.z);
		GETLINE("ROTATION %f, %f, %f", &m_Objects[i].m_rotation.x, &m_Objects[i].m_rotation.y, &m_Objects[i].m_rotation.z);
		GETLINE("SCALE %f, %f, %f", &m_Objects[i].m_scale.x, &m_Objects[i].m_scale.y, &m_Objects[i].m_scale.z);
		fgets(line, 255, f);
		
		Matrix matScale, matRotation, matPostion;
		Matrix matRX,matRY,matRZ;
		matRX.SetIdentity();
		matRY.SetIdentity();
		matRZ.SetIdentity();
		matRX.SetRotationY(m_Objects[i].m_rotation.x);
		matRY.SetRotationY(m_Objects[i].m_rotation.y);
		matRZ.SetRotationY(m_Objects[i].m_rotation.z);
		matPostion.SetIdentity();
		matScale.SetIdentity();
		matRotation.SetIdentity();
		matScale.SetScale(m_Objects[i].m_scale);
		matPostion.SetTranslation(m_Objects[i].m_position);
		matRotation = matRZ * matRX * matRY;
		m_Objects[i].mWorldMatrix = matScale * matRotation * matPostion;
	}
	fclose(f);
	return 0;
}
void cSceneManager::Draw()
{
	glBindFramebuffer(GL_FRAMEBUFFER, fbo.framebuffer);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		
	for(int i = 0; i < m_numObject; ++i)
	{
		if(i == 8)
			;
		m_Objects[i].draw();
	}
	glBindFramebuffer(GL_FRAMEBUFFER, 0);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glUseProgram(myShaders.program);

	glBindBuffer(GL_ARRAY_BUFFER, model.vboIds[0]);

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model.vboIds[1]);

	glActiveTexture(GL_TEXTURE0);

	glBindTexture(GL_TEXTURE_2D, fbo.texture);
	
	glUniform1i(myShaders.u_texture0, 0);

	if (myShaders.positionAttribute != -1)
	{
		glEnableVertexAttribArray(myShaders.positionAttribute);
		glVertexAttribPointer(myShaders.positionAttribute, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), OFFSET_POS);
	}
	
	if (myShaders.uv_posAttribute != -1)
	{
		glEnableVertexAttribArray(myShaders.uv_posAttribute);
		glVertexAttribPointer(myShaders.uv_posAttribute, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void *) OFFSET_UV);
	}
	
	glDrawElements(GL_TRIANGLES, model.numIndices, GL_UNSIGNED_INT, 0);

	glBindBuffer(GL_ARRAY_BUFFER, 0);

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

	glBindFramebuffer(GL_FRAMEBUFFER, 0);

}
void cSceneManager::Update( float deltaTime )
{ 
	totalTime+= deltaTime;
	
	for(int i = 0; i < m_numObject; ++i)
	{
		if(m_Objects[i].id == 0){
			m_Objects[i].m_rotation.y += deltaTime;		
		
		}
		m_Objects[i].update(deltaTime);
	}
}

